**串口传输大量数据时 总线空闲中断+DMA传输 为CPU减负** 您所在的位置:网站首页 dma传输时 cpu工作状态 **串口传输大量数据时 总线空闲中断+DMA传输 为CPU减负**

**串口传输大量数据时 总线空闲中断+DMA传输 为CPU减负**

2024-02-25 19:00| 来源: 网络整理| 查看: 265

串口传输大量数据时 总线空闲中断+DMA传输 为CPU减负 在使用串口接受数据时,如果用while在主函数等待,或者用if在主函数判断,传输少量的标志位可以,程序效率很低,如果用DMA+单字节串口接受中断,这样效率高了,但是当我们需要不间断传输大量数据时,单片机频繁进入中断,有时会影响main()函数的运行,如果采用串口总线空闲触发中断+DMA传输,可以完美的解决这两个问题。 USART_SR寄存器的IDLE位该位的作用时当检测到总线空闲时触发中断,用此标志位我们可以在传输完一帧数据时进入一次中断,这样进入中断次数缩减,main()效率增加 代码如下:

/******************************************************************************** * @file LSYY_Usart_Api.c * @author 绿水颖颖 * @version V1.0 * @date 2017.7.26 * @brief 传输大量数据时 空闲中断+DMA传输 为CPU减负 ****************************************************************************** * @attention * * ********************************************************************************/ #include "LSYY_Usart_Api.h" #include "LSYY_usart.h" #include "LSYY_led.h" /*内存池*/ uint8_t DMA_Rece_Buf[USART_RX_BUFF_SIZE]; /* *函数名` : void USURT1_Config(void) *描述 :配置USART1 *输入 :无 *输出 :无 */ void USART_Config(void) { GPIO_InitTypeDef GPIO_InitStructure ; USART_InitTypeDef USART_InitStructure ; //开启串口的时钟 DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK ,ENABLE); //开启GPIO的时钟 DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK,ENABLE); //配置串口1的寄存器 //配置串口1所对应的GPIO口 //配置模式 复用推挽输出模式 GPIO_InitStructure.GPIO_Pin=DEBUG_USART_TX_GPIO_PIN; GPIO_InitStructure.GPIO_Mode =GPIO_Mode_AF_PP ; //配置输出速率 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //初始化GPIO口 GPIO_Init(DEBUG_USART_TX_GPIO_PORT,&GPIO_InitStructure); //配置串口1GPIO口的模式 //GPIOA10 //GPIO_InitStructure.GPIO_Pin=DEBUG_USART_RX_GPIO_PORT_PIN; GPIO_InitStructure.GPIO_Pin=DEBUG_USART_RX_GPIO_PIN; //配置串口模式 GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IN_FLOATING ; //初始化GPIOA GPIO_Init(DEBUG_USART_RX_GPIO_PORT,&GPIO_InitStructure); //配置串口 //设置波特率 USART_InitStructure.USART_BaudRate =DEBUG_USART_BAUDRATE ; //设置传输字节 USART_InitStructure.USART_WordLength=USART_WordLength_8b; //设置停止标志位 USART_InitStructure.USART_StopBits=USART_StopBits_1; //配置奇偶校检位,不设置 USART_InitStructure.USART_Parity=USART_Parity_No; //配置硬件控制流,不配置 USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None ; //配置串口模式 USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx ; //初始化串口1 USART_Init(DEBUG_USARTx ,&USART_InitStructure); /****************************************************注意**************************************************/ /*开启空闲中断*/ USART_ITConfig(USART1, USART_IT_IDLE, ENABLE); /*开启DMA传输数据*/ USART_DMACmd(USART1,USART_DMAReq_Rx,ENABLE); //使能串口 USART_Cmd(DEBUG_USARTx ,ENABLE); USART_ClearFlag(USART1, USART_FLAG_TC); } /** * @brief 串口空闲中断(IDLE)无 * @param 无 * @retval 无 **/ void USART_IDLE_NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; /* 配置中断源:IDLE */ NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; /* 配置抢占优先级 */ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; /* 配置子优先级 */ NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; /* 使能中断通道 */ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //初始化 NVIC_Init(&NVIC_InitStructure); } /** * @brief USART1 DMA配置 * @param 无 * @retval 无 **/ void USART_DMA_Config(void) { DMA_InitTypeDef DMA_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能DMA传输 //相应的DMA配置 DMA_DeInit(DMA1_Channel5); //将DMA的通道5寄存器重设为缺省值 串口1对应的是DMA通道5 //DMA外设ADC基地址 DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&USART1->DR; //DMA内存基地址 DMA_InitStructure.DMA_MemoryBaseAddr = (u32)DMA_Rece_Buf; //数据传输方向,从外设读取发送到内存 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //DMA通道的DMA缓存的大小 DMA_InitStructure.DMA_BufferSize = USART_RX_BUFF_SIZE; //外设地址寄存器不变 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //内存地址寄存器递增 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //数据宽度为8位 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //数据宽度为8位 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //工作在正常缓存模式 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //DMA通道 x拥有中优先级 DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA通道x没有设置为内存到内存传输 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //根据DMA_InitStruct中指定的参数初始化DMA的通道USART1_Tx_DMA_Channel所标识的寄存器 DMA_Init(DMA1_Channel5, &DMA_InitStructure); //正式驱动DMA传输 DMA_Cmd(DMA1_Channel5, ENABLE); } /** * @brief 串口DMA配置复位函数 恢复DMA指针 * @param 无 * @retval 无 **/ void DeInit_USART_DMA(DMA_Channel_TypeDef*DMA_CHx) { //串口DMA失能 DMA_Cmd(DMA_CHx,DISABLE); /*DMA传输数值重装*/ DMA_SetCurrDataCounter(DMA_CHx,USART_RX_BUFF_SIZE); //串口DMA使能 DMA_Cmd(DMA_CHx,ENABLE); } /** * @brief 串口发送一个数组、字符串 * @param buf 字符串数组地址 len 数组字符串长度 * @retval 无 **/ void Usart1_Send(u8 *buf,u8 len) { u8 t; //循环发送数据 for(t=0;t


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有